using System;
using System.Text;
using System.Data;
using System.Collections;
using System.Collections.Generic;

using Framework;

namespace SchemaMonitor
{
    //Table-Row Class (Customisable half)
    public partial class CPublish
    {
        #region Constants
        //Join Expressions
        //private static string JOIN_SAMPLE = String.Concat(TABLE_NAME, " LEFT OUTER JOIN ", CSample.TABLE_NAME, " ON PublishSampleId=SampleId");
        #endregion

        #region Constructors (Public)
        //Default Connection String
        public CPublish() : base() {}
        public CPublish(int publishId) : base(publishId) {}
        
        //Alternative Connection String
        public CPublish(CDataSrc dataSrc) : base(dataSrc) {}
        
        public CPublish(CDataSrc dataSrc, int publishId) : base(dataSrc, publishId) {}
        
        //Transactional (shares an open connection)
        protected internal CPublish(CDataSrc dataSrc, int publishId, IDbTransaction txOrNull) : base(dataSrc, publishId, txOrNull) {}        
        #endregion

        #region Default Values
        protected override void InitValues_Custom()
        {
			//Custom default values (e.g. DateCreated column)
			//Member variables (e.g. for child collections)
			_publishChapters = new CPublishChapterList();
			_publishSections = new CPublishSectionList();
			_publishImages = new CPublishImageList();

		}
		#endregion

		#region Default Connection String
		protected override CDataSrc DefaultDataSrc()  { return CDataSrc.Default;  }
		#endregion

		#region Members
		//Foreign Keys

		//Child Collections  
		[NonSerialized()]
		private CPublishChapterList _publishChapters;
		[NonSerialized()]
		private CPublishSectionList _publishSections;
		[NonSerialized()]
		private CPublishImageList _publishImages;

		//Xml Data (as high-level objects)

		#endregion

		#region Properties - Relationships
		//Relationships - Foriegn Keys (e.g parent)

		//Relationships - Collections (e.g. children)
		public CPublishChapterList PublishChapters
		{
			get
			{
				if (_publishChapters == null)
				{
					lock (this)
					{
						if (_publishChapters == null)
						{
							_publishChapters = new CPublishChapter(DataSrc).SelectByPublishId(this.PublishId);
							_publishChapters.Publish = this;
						}
					}
				}
				return _publishChapters;
			}
			set
			{
				_publishChapters = value;
				if (null != value)
					_publishChapters.Publish = this;
			}
		}
		protected CPublishChapterList PublishChapters_(IDbTransaction tx)   //Only used for cascade deletes
		{
			return new CPublishChapter(DataSrc).SelectByPublishId(this.PublishId, tx);
		}
		public int PublishChaptersCount()
		{
			if (null != _publishChapters) return _publishChapters.Count;
			return new CPublishChapter(DataSrc).SelectCountByPublishId(this.PublishId);
		}


		public CPublishSectionList PublishSections
		{
			get
			{
				if (_publishSections == null)
				{
					lock (this)
					{
						if (_publishSections == null)
						{
							_publishSections = new CPublishSection(DataSrc).SelectByPublishId(this.PublishId);
							_publishSections.Publish = this;
						}
					}
				}
				return _publishSections;
			}
			set
			{
				_publishSections = value;
				if (null != value)
					_publishSections.Publish = this;
			}
		}
		protected CPublishSectionList PublishSections_(IDbTransaction tx)   //Only used for cascade deletes
		{
			return new CPublishSection(DataSrc).SelectByPublishId(this.PublishId, tx);
		}
		public int PublishSectionsCount()
		{
			if (null != _publishSections) return _publishSections.Count;
			return new CPublishSection(DataSrc).SelectCountByPublishId(this.PublishId);
		}



		public CPublishImageList PublishImages
		{
			get
			{
				if (_publishImages == null)
				{
					lock (this)
					{
						if (_publishImages == null)
						{
							_publishImages = new CPublishImage(DataSrc).SelectByPublishId(this.PublishId);
							_publishImages.Publish = this;
						}
					}
				}
				return _publishImages;
			}
			set
			{
				_publishImages = value;
				if (null != value)
					_publishImages.Publish = this;
			}
		}
		protected CPublishImageList PublishImages_(IDbTransaction tx)   //Only used for cascade deletes
		{
			return new CPublishImage(DataSrc).SelectByPublishId(this.PublishId, tx);
		}
		public int PublishImagesCount()
		{
			if (null != _publishImages) return _publishImages.Count;
			return new CPublishImage(DataSrc).SelectCountByPublishId(this.PublishId);
		}

		#endregion

		#region Properties - Customisation
		//Derived/ReadOnly (e.g. xml classes, presentation logic)
		#endregion

		#region Save/Delete Overrides
		//Can Override base.Save/Delete (e.g. Cascade deletes, or insert related records)
		public override void Delete(IDbTransaction txOrNull)
		{
			//Use a transaction if none supplied 
			if (txOrNull == null)
			{
				BulkDelete(this);
				return;
			}

			//Cascade-Delete (all child collections) 
			this.PublishChapters_(txOrNull).DeleteAll(txOrNull);
			this.PublishSections_(txOrNull).DeleteAll(txOrNull);
			this.PublishImages_(txOrNull).DeleteAll(txOrNull);

			//Normal Delete 
			base.Delete(txOrNull);
		}
		#endregion

		#region Custom Database Queries
		//For Stored Procs can use: MakeList (matching schema), or DataSrc.ExecuteDataset (reports etc)
		//For Dynamic sql, can use: SelectSum, SelectDistinct, SelectCount, SelectWhere (inherited methods)
		//                see also: SelectBy[FK], Search and Count (auto-generated sample queries)
		#endregion

		#region Searching (Optional)
		//Dynamic search methods: (overload as required for common search patterns, cascade the BuildWhere overloads)
		//   Public  x5 - Simple, Paged, Transactional, Count, and Dataset
		//   Private x1 - BuildWhere
		//See also in-memory search options in list class, such as GetBy[FK] and Search

		//Simple
		public CPublishList SelectSearch(string nameOrId /**/)  {   return SelectWhere(BuildWhere(nameOrId /**/));  } //, JOIN_OR_VIEW); }

        //Paged
        public CPublishList SelectSearch(CPagingInfo pi, string nameOrId /*,  */)
        {
            //pi.TableName = JOIN_OR_VIEW
            return SelectWhere(pi, BuildWhere(nameOrId /**/));
        }

        //Transactional
        public CPublishList SelectSearch(string nameOrId, /* , */ IDbTransaction tx)   {   return SelectWhere(BuildWhere(nameOrId /*,  */), tx);   }   //, JOIN_OR_VIEW, tx); }

        //Dataset (e.g. ExportToCsv)
        public DataSet SelectSearch_Dataset(string nameOrId /*, */)   {   return SelectWhere_Dataset(BuildWhere(nameOrId /*,  */));   }   //, JOIN_OR_VIEW); }

        //Count
        public int SelectCount(string nameOrId /*, */)   {   return SelectCount(BuildWhere(nameOrId /*,  */));   }   //, JOIN_OR_VIEW); }

        //Filter Logic
        private CCriteriaList BuildWhere(string nameOrId /*,  */)
        {
            CCriteriaList where = new CCriteriaList();  //Defaults to AND logic
            
            //Simple search box UI
            if (!string.IsNullOrEmpty(nameOrId)) 
            {
                //Interpret search string in various ways using OR sub-expression
                CCriteriaGroup orExpr = new CCriteriaGroup(EBoolOperator.Or);
                
                //Special case - search by PK
                /* 
                int id = 0;
                if (int.TryParse(nameOrId, out id))
                    orExpr.Add("PublishId", id); 
                */
                
                //Search a range of string columns
                string wildCards = string.Concat("%", nameOrId, "%");

                //Conclude
                if (orExpr.Group.Count > 0)
                    where.Add(orExpr);
            }
            
			//Other search Colums (customise as required)

            return where;
        }
        #endregion


        #region Cloning
        public CPublish Clone(CDataSrc target, IDbTransaction txOrNull) //, int parentId)
        {
            //Shallow copy: Copies the immediate record, excluding autogenerated Pks
            CPublish copy = new CPublish(this, target);

            //Deep Copy - Child Entities: Cloned children must reference their cloned parent
            //copy.SampleParentId = parentId;

            copy.Save(txOrNull);

            //Deep Copy - Parent Entities: Cloned parents also clone their child collections
            //this.Children.Clone(target, txOrNull, copy.PublishId);

            return copy;
        }
        #endregion

        #region ToXml
        protected override void ToXml_Custom(System.Xml.XmlWriter w)
        {
            //Store(w, "Example", this..Example)
        }
        #endregion
    }
}